<template>
  <div ref="chartRef" :style="{ height, width }"></div>
</template>

<script lang="ts">
  import { defineComponent, PropType, Ref, ref, watchEffect } from 'vue';
  import { useECharts } from '/@/hooks/web/useECharts';
  import * as MathUtil from '/@/utils/MathUtil';

  const COLOR_BLUE = '#212A7C';
  const COLOR_PURPLE = '#665C99';
  const COLOR_WARN = '#FDA757';
  const COLOR_RED = '#F53F3F';

  export default defineComponent({
    name: 'IncomeLine',
    props: {
      width: {
        type: String as PropType<string>,
        default: '100%',
      },
      height: {
        type: String as PropType<string>,
        default: '400px',
      },
      chartData: {
        type: Array as PropType<any[]>,
        required: true,
      },
    },
    setup(props) {
      const chartRef = ref<HTMLDivElement | null>(null);
      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);

      const getOption = () => {
        const orderMap = {
          客房收入: 0,
          餐饮收入: 1,
          其他收入: 2,
          GOP: 3,
          NPI: 4,
        };

        const sortedData = [...props.chartData].sort((a, b) => {
          return (orderMap[a.subjectName] ?? 999) - (orderMap[b.subjectName] ?? 999);
        });
        // 首先计算数据中的最大最小值
        // const allValues = props.chartData.flatMap((item) => [item.actual, item.budget, item.lActual]);
        // const maxValue = Math.max(...allValues);
        // const minValue = Math.min(...allValues);
        // const range = maxValue - minValue;
        // 首先计算是否有负数
        const hasNegativeValue = sortedData.some((item) => item.actual < 0 || item.budget < 0 || item.lActual < 0);

        return {
          backgroundColor: '#FFFFFF',
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow',
            },
            formatter: (params: any) => {
              let result = `${params[0].name}<br/>`;
              params.forEach((param: any) => {
                if (param.seriesName === '去年同期线') return;
                result += `${param.seriesName}：${MathUtil.currencyWNFormatter(param.value, 0)}万元<br/>`;
              });
              return result;
            },
          },
          grid: {
            left: '5%',
            right: '5%',
            bottom: '3%',
            top: '15%',
            containLabel: true,
          },
          // legend: {
          //   data: ['实际', '预算', '去年同期', '平均值'],
          //   right: 10,
          //   top: 10,
          //   itemWidth: 10,
          //   itemHeight: 10,
          //   textStyle: {
          //     fontSize: 12,
          //     color: '#666'
          //   }
          // },
          yAxis: {
            type: 'value',
            splitNumber: 10,
            axisLine: {
              show: true,
              lineStyle: {
                color: '#000',
                width: 1,
              },
              symbol: hasNegativeValue ? ['arrow', 'arrow'] : ['none', 'arrow'],
              symbolOffset: [0, 6],
              symbolSize: [6, 10],
            },
            axisTick: {
              show: true,
              length: 5,
              lineStyle: {
                color: '#000',
              },
            },
            splitLine: {
              show: false,
              lineStyle: {
                type: 'dashed',
                color: '#E9E9E9',
              },
            },
            axisLabel: {
              formatter: (value: number) => {
                return MathUtil.currencyWNFormatter(value, 0);
              },
              color: '#666',
            },
          },
          xAxis: {
            type: 'category',
            data: sortedData.map((item) => item.subjectName),
            axisLine: {
              show: true,
              lineStyle: {
                color: '#000',
                width: 1,
              },
              symbol: ['none', 'arrow'],
              symbolOffset: [6, 0],
              symbolSize: [6, 10],
            },
            axisTick: {
              show: false,
            },
            splitLine: {
              show: false,
            },
            axisLabel: {
              color: '#666',
              fontSize: 12,
              align: 'center',
            },
          },
          series: [
            {
              name: '实际',
              type: 'bar',
              barWidth: 45,
              barGap: '-70%',
              z: 2,
              itemStyle: {
                color: (params: any) => {
                  return params.value < 0 ? COLOR_RED : COLOR_BLUE;
                },
                barBorderRadius: [5, 5, 5, 5],
              },
              data: sortedData.map((item) => item.actual),
            },
            {
              name: '预算',
              type: 'bar',
              barWidth: 45,
              z: 1,
              itemStyle: {
                color: (params: any) => {
                  return params.value < 0 ? COLOR_RED : COLOR_PURPLE;
                },
                barBorderRadius: [5, 5, 5, 5],
              },
              data: sortedData.map((item) => item.budget),
            },
            {
              name: '去年同期',
              type: 'custom',
              renderItem: function (params, api) {
                const xValue = api.value(0);
                const yValue = api.value(1);
                const point = api.coord([xValue, yValue]);

                return {
                  type: 'group',
                  children: [
                    {
                      type: 'line',
                      shape: {
                        x1: point[0] - 23,
                        y1: point[1],
                        x2: point[0] + 30,
                        y2: point[1],
                      },
                      style: {
                        stroke: '#FF8D23',
                        lineDash: [4, 4],
                        lineWidth: 2,
                      },
                    },
                    {
                      type: 'path',
                      shape: {
                        pathData: `M ${point[0] - 35} ${point[1] - 8} l 12 8 l -12 8 z`,
                      },
                      style: {
                        fill: '#FF8D23',
                      },
                    },
                  ],
                };
              },
              data: sortedData.map((item) => item.lActual),
            },
            {
              name: '平均值',
              type: 'custom',
              renderItem: function (params, api) {
                const xValue = api.value(0);
                const yValue = api.value(1);
                const point = api.coord([xValue, yValue]);

                return {
                  type: 'group',
                  children: [
                    {
                      type: 'line',
                      shape: {
                        x1: point[0] - 23,
                        y1: point[1],
                        x2: point[0] + 30,
                        y2: point[1],
                      },
                      style: {
                        stroke: '#000',
                        lineDash: [4, 4],
                        lineWidth: 2,
                      },
                    },
                    {
                      type: 'path',
                      shape: {
                        pathData: `M ${point[0] - 35} ${point[1] - 6} l 12 6 l -12 6 z`,
                      },
                      style: {
                        fill: '#000',
                      },
                    },
                  ],
                };
              },
              data: sortedData.map((item) => ((item.actual || 0) + (item.budget || 0) + (item.lActual || 0)) / 3),
            },
          ],
        };
      };

      watchEffect(() => {
        if (props.chartData.length > 0) {
          setOptions(getOption());
        }
      });

      return { chartRef };
    },
  });
</script>

<style lang="less" scoped>
  .echarts {
    width: 100% !important;
    height: 100% !important;
    background-color: #ffffff;
    border-radius: 8px;
    padding: 16px;
  }
</style>
